﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UFIDA.U9.Base;
using UFIDA.U9.CBO.Pub.Controller;
using UFIDA.U9.CBO.SCM.Item;
using UFIDA.U9.CBO.SCM.PropertyTypes;
using UFIDA.U9.CBO.SCM.Warehouse;
using UFIDA.U9.Cust.YYD.PlugBE.Dtos;
using UFIDA.U9.Cust.YYD.PlugBE.Public;
using UFIDA.U9.InvDoc.CostAdjust;
using UFIDA.U9.InvDoc.Enums;
using UFIDA.U9.InvDoc.MiscRcv;
using UFIDA.U9.ISV.CostAdjustISV.Proxy;
using UFIDA.U9.ISV.MiscRcvISV;
using UFIDA.U9.ISV.MiscRcvISV.Proxy;
using UFIDA.U9.PM.PO;
using UFIDA.U9.PM.Rcv;
using UFSoft.UBF.Business;
using UFSoft.UBF.Transactions;

namespace UFIDA.U9.Cust.YYD.PlugBE.ReceivementP
{
    public class BeforeUpdating : UFSoft.UBF.Eventing.IEventSubscriber
    {
        public void Notify(params object[] args)
        {
            #region 从事件参数中取得当前业务实体													 
            if (args == null || args.Length == 0 || !(args[0] is UFSoft.UBF.Business.EntityEvent))
                return;
            BusinessEntity.EntityKey key = ((UFSoft.UBF.Business.EntityEvent)args[0]).EntityKey;
            if (key == null)
                return;
            var holder = key.GetEntity() as UFIDA.U9.PM.Rcv.Receivement;
            if (holder == null)
                return;
            #endregion

            //审核触发委外废料自动杂收管理
            if (holder.OriginalData.Status != PM.Rcv.RcvStatusEnum.Closed && holder.Status == PM.Rcv.RcvStatusEnum.Closed)
            {
                //判断是否有需要生成杂收单的行
                var rcvlines = holder.RcvLines.Cast<RcvLine>().ToList();
                if (rcvlines.Any())
                {
                    //生成杂收单
                    CommonCreateMiscRcvProxy CreateMRSV = new CommonCreateMiscRcvProxy();
                    List<IC_MiscRcvDTOData> dtos = new List<IC_MiscRcvDTOData>();
                    IC_MiscRcvDTOData miscDTO = new IC_MiscRcvDTOData();
                    miscDTO.BusinessDate = holder.BusinessDate;
                    miscDTO.BenefitOrg = Context.LoginOrg.ID;
                    MiscRcvDocType miscshipdoctype = MiscRcvDocType.Finder.Find($"Code = 'MR10' and Org = '{Context.LoginOrg.ID}'") ?? throw new Exception($"委外废料联产品收货：生成杂收单失败，当前组织下未找到编码为MR10的杂收单单据类型");
                    miscDTO.MiscRcvDocType = new CommonArchiveDataDTOData
                    {
                        ID = miscshipdoctype.ID,
                        Code = miscshipdoctype.Code
                    };
                    miscDTO.MiscRcvTransLs = new List<IC_MiscRcvTransLsDTOData>();
                    List<long> BOMItemIDs = rcvlines.Select(t => t.ItemInfo.ItemID.ID).Distinct().ToList();
                    var ds = PublicMethod.RunSQL($@"
select bomm.ItemMaster BOMItem,dp.ItemMaster,dpitem.Code ItemCode,dp.ForecastQty,suc.UnitCost_MaterialCurrentCost Price
from CBO_BOMMaster bomm
inner join CBO_DegreePercent dp on dp.BOMMaster = bomm.ID and dp.ProductType != 0
inner join CBO_ItemMaster dpitem on dp.ItemMaster = dpitem.ID
left join CA_StdUnitCost suc on suc.ItemMaster = dp.ItemMaster and GETDATE() between suc.FromDate and suc.ToDate
where GETDATE() between bomm.EffectiveDate and bomm.DisableDate and bomm.ItemMaster in ({string.Join(",", BOMItemIDs)})
");
                    var OtherItemList = PublicMethod.DataRowsToList<OtherItemDto>(ds.Tables[0].Rows);
                    foreach (var rcvline in rcvlines)
                    {
                        //找每行的联产品列表，可能有多个
                        var OtherItems = OtherItemList.Where(t => t.BOMItem == rcvline.ItemInfo.ItemID.ID).ToList();
                        foreach (var item in OtherItems)
                        {
                            if (item.Price == 0)
                            {
                                throw new Exception($"委外废料联产品收货：未找到联产品{item.ItemCode}的定额成本，请维护。");
                            }
                            IC_MiscRcvTransLsDTOData lDTOData = new IC_MiscRcvTransLsDTOData();
                            lDTOData.ItemInfo = new ItemInfoData()
                            {
                                ItemCode = item.ItemCode
                            };
                            lDTOData.StoreUOMQty = item.ForecastQty * rcvline.RcvQtyTU;
                            lDTOData.CostUOMQty = item.ForecastQty * rcvline.RcvQtyTU;
                            lDTOData.DescFlexSegments = new Base.FlexField.DescFlexField.DescFlexSegmentsData
                            {
                                PrivateDescSeg1 = holder.DocNo,
                                PrivateDescSeg2 = rcvline.DocLineNo.ToString()
                            };
                            //仓库
                            //深圳
                            var poline = POLine.Finder.FindByID(rcvline.SrcDoc.SrcDocLine.EntityID);
                            if (poline != null)
                            {
                                string whCode = "";
                                if (poline.DescFlexSegments.PubDescSeg2 == "1008")
                                    whCode = "SZ007";
                                else if (poline.DescFlexSegments.PubDescSeg2 == "1010")
                                    whCode = "SZ010";
                                else if (poline.DescFlexSegments.PubDescSeg2.StartsWith("2"))
                                {
                                    var ahWh = Warehouse.Finder.Find($"DescFlexField.PrivateDescSeg1 = '{holder.Supplier.Code}'");
                                    whCode = ahWh?.Code;
                                }
                                lDTOData.Wh = new CommonArchiveDataDTOData
                                {
                                    Code = whCode
                                };
                                lDTOData.CostPrice = item.Price;
                                lDTOData.CostMny = Math.Round(lDTOData.CostUOMQty * lDTOData.CostPrice, 2, MidpointRounding.AwayFromZero);

                                miscDTO.MiscRcvTransLs.Add(lDTOData);
                            }
                        }
                    }
                    //生成成本调整单
                    CommonCreateCostAdjustProxy caSV = new CommonCreateCostAdjustProxy();
                    ISV.CostAdjustISV.IC_CostAdjustDTOData CADto = new ISV.CostAdjustISV.IC_CostAdjustDTOData();
                    CADto.BusinessDate = holder.BusinessDate;
                    CADto.CostAdjustDocType = new CommonArchiveDataDTOData
                    {
                        Code = "CostAdj002"
                    };
                    CADto.CostAdjustL = new List<ISV.CostAdjustISV.IC_CostAdjustLDTOData>();
                    foreach (var rcvline in rcvlines)
                    {
                        ISV.CostAdjustISV.IC_CostAdjustLDTOData caline = new ISV.CostAdjustISV.IC_CostAdjustLDTOData();
                        caline.ItemInfo = new ItemInfoData { ItemID = rcvline.ItemInfo.ItemID.ID };
                        caline.Wh = new CommonArchiveDataDTOData { ID = rcvline.Wh.ID };
                        caline.Lot = new LotInfoData { LotCode = rcvline.InvLotCode };
                        caline.Project = new CommonArchiveDataDTOData { ID = rcvline.Project?.ID ?? 0 };
                        caline.AdjustTo = 1;//减少
                        caline.AdjustAmt = OtherItemList.Where(t => t.BOMItem == rcvline.ItemInfo.ItemID.ID).Sum(t => t.ForecastQty * rcvline.RcvQtyTU * t.Price);
                        caline.AdjustAmt = Math.Round(caline.AdjustAmt, 2, MidpointRounding.AwayFromZero);
                        caline.SrcDocTypeEnum = 2;//收货单
                        caline.SrcDocEntityType = "UFIDA.U9.PM.Rcv.Receivement";
                        caline.SrcDoc = holder.ID;
                        caline.SrcDocNo = holder.DocNo;
                        caline.SrcDocLEntityType = "UFIDA.U9.PM.Rcv.RcvLine";
                        caline.SrcDocL = rcvline.ID;
                        caline.SrcDocLineNo = rcvline.DocLineNo;
                        caline.CostAdjustSL = new List<ISV.CostAdjustISV.IC_CostAdjustSLDTOData>();
                        ISV.CostAdjustISV.IC_CostAdjustSLDTOData casline = new ISV.CostAdjustISV.IC_CostAdjustSLDTOData();
                        casline.ItemAmt = caline.AdjustAmt;
                        caline.CostAdjustSL.Add(casline);
                        CADto.CostAdjustL.Add(caline);
                    }
                    //调用服务
                    if (miscDTO.MiscRcvTransLs.Count > 0)
                    {
                        using (UBFTransactionScope scope = new UBFTransactionScope(TransactionOption.RequiresNew))
                        {
                            try
                            {
                                CreateMRSV.MiscRcvDTOList = new List<IC_MiscRcvDTOData> { miscDTO };
                                //生成杂收
                                var result = CreateMRSV.Do();
                                if (result != null && result.Any())
                                {
                                    //审核杂收
                                    foreach (CommonArchiveDataDTOData dataDTOData in result)
                                    {
                                        MiscRcvTrans miscRcv = MiscRcvTrans.Finder.FindByID(dataDTOData.ID);

                                        using (ISession session = Session.Open())
                                        {
                                            miscRcv.Status = INVDocStatus.Approving;
                                            miscRcv.CurrAction = ActivityEnum.UIUpdate;
                                            session.Commit();
                                        }
                                        using (ISession session2 = Session.Open())
                                        {
                                            miscRcv.Status = INVDocStatus.Approved;
                                            miscRcv.CurrAction = ActivityEnum.UIUpdate;
                                            miscRcv.ApprovedBy = Context.LoginUser;
                                            miscRcv.ApprovedOn = Context.OperationDate;
                                            session2.Commit();
                                        }
                                    }
                                }
                                //生成成本调整单
                                caSV.CostAdjustDTOList = new List<ISV.CostAdjustISV.IC_CostAdjustDTOData> { CADto };
                                var caResult = caSV.Do();
                                if (caResult != null && caResult.Any())
                                {
                                    foreach (var item in caResult)
                                    {
                                        var costAdjust = CostAdjust.Finder.FindByID(item.ID);
                                        using (ISession session = Session.Open())
                                        {
                                            costAdjust.Status = INVDocStatus.Approving;
                                            costAdjust.CurrAction = CostAdjustActionEnum.UIUpdate; ;
                                            session.Commit();
                                        }
                                        using (ISession session2 = Session.Open())
                                        {
                                            costAdjust.Status = INVDocStatus.Approved;
                                            costAdjust.CurrAction = CostAdjustActionEnum.UIUpdate;
                                            costAdjust.ApprovedBy = Context.LoginUser;
                                            costAdjust.ApprovedOn = Context.OperationDate;
                                            session2.Commit();
                                        }
                                    }
                                }
                                scope.Commit();
                            }
                            catch (Exception ex)
                            {
                                scope.Rollback();
                                throw;
                            }
                        }
                    }
                }
            }
        }
    }
}
